Conversation
code-crusher
commented
Dec 26, 2025
- fix race condition with the isUserInput flag
- API Streaming Failed to have retry button
- fix previous commands still show run/reject buttons
- better checkpoint handling
- feat: migrate KiloTaskHeader and TaskItem to use ReadOnlyChatText
- add chat renderer
MIGRATION CHANGES: - Update KiloTaskHeader.tsx to import and use ReadOnlyChatText component - Replace custom highlightText function calls with ReadOnlyChatText - Remove unused highlighting functions (highlightSlashCommands, highlightMentions, highlightText) - Update TaskItem.tsx to use ReadOnlyChatText for consistent text rendering - Remove unused highlight property from DisplayHistoryItem interface - Remove empty DisplayHistoryItem interface to fix linting warning LINTING FIXES: - Clean up unused imports (validateSlashCommand, mentionRegexGlobal, vscode) - Remove unused customModes variable in KiloTaskHeader - Remove unused Mention import in ChatRow.tsx - Remove unused imports in ChatTextArea.tsx (getIconForFilePath, getIconUrlByName, formatMentionChipParts, getFileIconForMention, valueToHtml) - Remove unused mentionRegex import in ReadOnlyChatText.tsx BENEFITS: - Provides better text formatting with HTML conversion and mention support - Maintains all existing styling and layout functionality - Improves code consistency across chat components - Eliminates custom highlighting logic in favor of established component
| const mentionMapRef = useRef<Map<string, string>>(new Map()) | ||
|
|
||
| useEffect(() => { | ||
| const w = window as any | ||
| setMaterialIconsBaseUri(w.MATERIAL_ICONS_BASE_URI) | ||
| }, []) | ||
|
|
||
| // Build mention map similar to ChatTextArea | ||
| useEffect(() => { | ||
| mentionMapRef.current.clear() | ||
|
|
||
| // Add opened tabs to mention map | ||
| openedTabs | ||
| .filter((tab) => tab.path) | ||
| .forEach((tab) => { | ||
| const fullPath = "/" + tab.path | ||
| const segments = fullPath.split("/").filter(Boolean) | ||
| const filename = segments.pop() || fullPath | ||
| mentionMapRef.current.set(filename, fullPath) | ||
| }) | ||
|
|
||
| // Add file paths to mention map (excluding already added opened tabs) | ||
| filePaths | ||
| .map((file) => "/" + file) | ||
| .filter((path) => !openedTabs.some((tab) => tab.path && "/" + tab.path === path)) | ||
| .forEach((fullPath) => { | ||
| const segments = fullPath.split("/").filter(Boolean) | ||
| const filename = segments.pop() || fullPath | ||
| mentionMapRef.current.set(filename, fullPath) | ||
| }) | ||
| }, [filePaths, openedTabs]) | ||
|
|
||
| const htmlContent = useMemo(() => { | ||
| if (!value) return '<br data-plain-break="true">' | ||
| return valueToHtml(value, materialIconsBaseUri, mentionMapRef.current, customModes) | ||
| }, [value, materialIconsBaseUri, customModes]) |
There was a problem hiding this comment.
🟡 Bug / Reactivity
Issue: mentionMapRef is not reactive. If filePaths or openedTabs change (e.g., user opens a new file), the htmlContent will not re-render to highlight the new file mentions because useMemo does not track ref mutations.
Fix: Use useMemo to derive mentionMap directly, ensuring htmlContent updates when dependencies change.
Impact: Ensures correct syntax highlighting for file mentions as the workspace context changes.
| const mentionMapRef = useRef<Map<string, string>>(new Map()) | |
| useEffect(() => { | |
| const w = window as any | |
| setMaterialIconsBaseUri(w.MATERIAL_ICONS_BASE_URI) | |
| }, []) | |
| // Build mention map similar to ChatTextArea | |
| useEffect(() => { | |
| mentionMapRef.current.clear() | |
| // Add opened tabs to mention map | |
| openedTabs | |
| .filter((tab) => tab.path) | |
| .forEach((tab) => { | |
| const fullPath = "/" + tab.path | |
| const segments = fullPath.split("/").filter(Boolean) | |
| const filename = segments.pop() || fullPath | |
| mentionMapRef.current.set(filename, fullPath) | |
| }) | |
| // Add file paths to mention map (excluding already added opened tabs) | |
| filePaths | |
| .map((file) => "/" + file) | |
| .filter((path) => !openedTabs.some((tab) => tab.path && "/" + tab.path === path)) | |
| .forEach((fullPath) => { | |
| const segments = fullPath.split("/").filter(Boolean) | |
| const filename = segments.pop() || fullPath | |
| mentionMapRef.current.set(filename, fullPath) | |
| }) | |
| }, [filePaths, openedTabs]) | |
| const htmlContent = useMemo(() => { | |
| if (!value) return '<br data-plain-break="true">' | |
| return valueToHtml(value, materialIconsBaseUri, mentionMapRef.current, customModes) | |
| }, [value, materialIconsBaseUri, customModes]) | |
| const mentionMap = useMemo(() => { | |
| const map = new Map<string, string>() | |
| // Add opened tabs to mention map | |
| openedTabs | |
| .filter((tab) => tab.path) | |
| .forEach((tab) => { | |
| const fullPath = "/" + tab.path | |
| const segments = fullPath.split("/").filter(Boolean) | |
| const filename = segments.pop() || fullPath | |
| map.set(filename, fullPath) | |
| }) | |
| // Add file paths to mention map (excluding already added opened tabs) | |
| filePaths | |
| .map((file) => "/" + file) | |
| .filter((path) => !openedTabs.some((tab) => tab.path && "/" + tab.path === path)) | |
| .forEach((fullPath) => { | |
| const segments = fullPath.split("/").filter(Boolean) | |
| const filename = segments.pop() || fullPath | |
| map.set(filename, fullPath) | |
| }) | |
| return map | |
| }, [filePaths, openedTabs]) | |
| const htmlContent = useMemo(() => { | |
| if (!value) return '<br data-plain-break="true">' | |
| return valueToHtml(value, materialIconsBaseUri, mentionMap, customModes) | |
| }, [value, materialIconsBaseUri, mentionMap, customModes]) |
|
✅ Reviewed the changes: Verified the cleanup in |
|
Note PR Review SkippedPR review skipped as no relevant changes found due to large diff hunk OR part of a non-reviewable file. 📄Files skipped in review
💡Tips to use MatterAICommand List
|